﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _11_自定义控件
{
    public partial class Form1 : Form
    {
        
        /// <summary>
        /// 运动方向
        /// </summary>
        Direction direction = Direction.None;
        /// <summary>
        /// 步长
        /// </summary>
        int Setp = 2;

        /// <summary>
        /// 更新列表的委托
        /// </summary>
        public static Action<List<Shape>> actionUpdateListBox;



        public Form1()
        {
            InitializeComponent();
            this.canvasControl1.MovePointX = 40;
            this.canvasControl1.MovePointY = 40;

            //设置滑块的值
            this.trackBar1.Value = Setp;//设置步长的滑块值
            this.trackBar2.Value = this.timer1.Interval;//设置定时器的滑块值
            //设置文本的值
            this.label3.Text = Setp.ToString();//设置步长的文本值
            this.label4.Text = this.timer1.Interval.ToString()+"MS";//设置定时器的文本值

            actionUpdateListBox = new Action<List<Shape>>(UpdateListBox);

        }

        private void canvasControl1_Load(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
        /// <summary>
        /// 定时器的响应时间
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            switch (direction)
            {
                case Direction.None:
                    break;
                case Direction.Up:
                    this.canvasControl1.MovePointY += Setp;
                    break;
                case Direction.Down:
                    this.canvasControl1.MovePointY -= Setp;
                    break;
                case Direction.Left:
                    this.canvasControl1.MovePointX -= Setp;
                    break;
                case Direction.Right:
                    this.canvasControl1.MovePointX += Setp;
                    break;
            }
        }

        private void button7_MouseDown(object sender, MouseEventArgs e)
        {
            direction = Direction.Up;
        }

        private void button7_MouseUp(object sender, MouseEventArgs e)
        {
            direction = Direction.None;
        }

        private void button8_MouseDown(object sender, MouseEventArgs e)
        {
            direction = Direction.Down;
        }



        private void button10_MouseDown(object sender, MouseEventArgs e)
        {
            direction = Direction.Right;
        }

        private void button9_MouseDown(object sender, MouseEventArgs e)
        {
            direction = Direction.Left;
        }
        /// <summary>
        /// 滚动条的滑动事件=>步长
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            //确保大于等于零
            if (this.trackBar1.Value >= 1)
            {
                Setp = this.trackBar1.Value;
                this.label3.Text = Setp.ToString();
            }
            else
            {
                this.trackBar1.Value = 1;//设置最小值
            }
        }
        /// <summary>
        /// 调整定时器的时间间隔
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void trackBar2_Scroll(object sender, EventArgs e)
        {
            //设置定时器的时间间隔，确保大于等于零
            if (this.trackBar2.Value >= 1)
            {
                this.timer1.Interval = this.trackBar2.Value;
                this.label4.Text = this.timer1.Interval.ToString() + "MS";
            }
            else
            {
                this.trackBar2.Value = 1;//设置最小值
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Frm_EditorNode frm_EditorNode = new Frm_EditorNode();
            if (frm_EditorNode.ShowDialog()==DialogResult.OK)
            {
                this.canvasControl1.NodeList.Add(frm_EditorNode.Node);
                //刷新控件显示
                this.canvasControl1.Invalidate();//强制刷新
                //绑定列表显示
                this.listBox1.DataSource = null;
                this.listBox1.DataSource = this.canvasControl1.NodeList;

            }
        }

        /// <summary>
        /// 九点坐标生成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button5_Click(object sender, EventArgs e)
        {
            //清空容器中的所有坐标点
            this.canvasControl1.NodeList.Clear();

            //定义坐标点的间隔
            int spacing = 80;//相邻点之间的间隔

            //创建九个坐标点，按照九宫格的方式进行排列
            NodeClass node1 = new NodeClass("1号点",-spacing,spacing,Color.Red);
            NodeClass node2 = new NodeClass("2号点", 0, spacing, Color.Red);
            NodeClass node3 = new NodeClass("3号点", spacing, spacing, Color.Red);
            NodeClass node4 = new NodeClass("4号点", -spacing, 0, Color.Red);
            NodeClass node5 = new NodeClass("5号点", 0, 0, Color.Red);
            NodeClass node6 = new NodeClass("6号点", spacing, 0, Color.Red);
            NodeClass node7 = new NodeClass("7号点", -spacing, -spacing, Color.Red);
            NodeClass node8 = new NodeClass("8号点", 0, -spacing, Color.Red);
            NodeClass node9 = new NodeClass("9号点", spacing, -spacing, Color.Red);

            //添加到集合中
            this.canvasControl1.NodeList.Add(node1);
            this.canvasControl1.NodeList.Add(node2);
            this.canvasControl1.NodeList.Add(node3);
            this.canvasControl1.NodeList.Add(node4);
            this.canvasControl1.NodeList.Add(node5);
            this.canvasControl1.NodeList.Add(node6);
            this.canvasControl1.NodeList.Add(node7);
            this.canvasControl1.NodeList.Add(node8);
            this.canvasControl1.NodeList.Add(node9);

            //刷新控件显示
            this.canvasControl1.Invalidate();//强制刷新

            //绑定列表显示
            this.listBox1.DataSource = null;
            this.listBox1.DataSource = this.canvasControl1.NodeList;

        }
        /// <summary>
        /// 生成轨迹-九点坐标轨迹
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button6_Click(object sender, EventArgs e)
        {
            //判断控件中的点是否足够
            if (this.canvasControl1.NodeList.Count<2)
            {
                //提示节点数量不足无法生成轨迹
                MessageBox.Show("节点数量不足，无法生成轨迹路径！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            //创建形状对象
            CustomPathShape customPathShape = new CustomPathShape("九点坐标轨迹路径",Color.Red);
            //由于是四象限的坐标系，需要进行坐标点转换=>像素的中心点
            Point ZeroPoint = new Point(this.canvasControl1.Width / 2, this.canvasControl1.Height / 2);
            //将节点坐标添加到轨迹路径中,而节点坐标存储在控件中，对控件的NodeClass节点进行遍历取出当中的坐标
            foreach (NodeClass item in this.canvasControl1.NodeList)
            {
                //进行坐标点转换，坐标轴的坐标转换为像素坐标
                Point shapePoint = new Point(ZeroPoint.X+ item.X, ZeroPoint.Y-item.Y);
                //转换后的坐标保存进入到自定义形状中
                customPathShape.Upadate(shapePoint);
            }
            //添加到形状集合中
            this.canvasControl1.ShapeList.Add(customPathShape);
            //刷新画布
            this.canvasControl1.Invalidate();
            //下方形状表格绑定更新
            UpdateListBox(this.canvasControl1.ShapeList);
        }

        public void UpdateListBox(List<Shape> shapes)
        {
            this.listBox2.DataSource = null;
            this.listBox2.DataSource= this.canvasControl1.ShapeList;            
        }


        /// <summary>
        /// 全部绘制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button16_Click(object sender, EventArgs e)
        {
            this.canvasControl1.StartAnimation();//启动绘制动画
        }

        private void button13_Click(object sender, EventArgs e)
        {
            if (this.button13.Text== "开始-绘制自定义轨迹")
            {
                this.canvasControl1.SetDrawingMode(DrawingMode.CustomPath);
                this.button13.Text = "结束-绘制自定义轨迹";
            }
            else
            {
                this.canvasControl1.SetDrawingMode(DrawingMode.None);
                this.button13.Text = "开始-绘制自定义轨迹";
            }
        }
        /// <summary>
        /// 绘制矩形
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button12_Click(object sender, EventArgs e)
        {
            this.canvasControl1.SetDrawingMode(DrawingMode.Rectangle);
        }

        /// <summary>
        /// 绘制圆形
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button11_Click(object sender, EventArgs e)
        {
            this.canvasControl1.SetDrawingMode(DrawingMode.Circle);
        }

        /// <summary>
        /// 清空形状
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button21_Click(object sender, EventArgs e)
        {
            this.canvasControl1.ShapeList.Clear();//清空形状
            this.canvasControl1.Invalidate();//强制重绘
            this.listBox2.DataSource = null;//清空绑定
        }

        /// <summary>
        /// 保存绘制的形状
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button14_Click(object sender, EventArgs e)
        {
            //创序列化文件，保存形状 (Application.StartupPath：程序启动路径)
            string filePath = Application.StartupPath + "\\ShapeData.kfc";
            //创建序列化对象
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            //创建文件流,指明写入硬盘当中的位置(using System.IO;)
            using (FileStream fs = new FileStream(filePath, FileMode.Create))
            {
                //序列化形状集合（用以将内存条数据写入到文件中）
                binaryFormatter.Serialize(fs, this.canvasControl1.ShapeList);
            }
        }
        /// <summary>
        /// 加载形状
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button15_Click(object sender, EventArgs e)
        {
            //指定序列化文件的路径
            string filePath = Application.StartupPath + "\\ShapeData.kfc";
            //创建序列化对象，用以反序列化(从硬盘加载到内存条)
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            //创建文件流，指明读取硬盘中的位置
            using (FileStream fs = new FileStream(filePath, FileMode.Open))
            {
                //反序列化形状集合
                this.canvasControl1.ShapeList = binaryFormatter.Deserialize(fs) as List<Shape>;
            }
            //刷新画布
            this.canvasControl1.Invalidate();
        }
    }
}
